package tut.fileLock.exclusive;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.NonReadableChannelException;
import java.nio.channels.NonWritableChannelException;

public class TryLock {

    public static void main(String[] args) throws Exception {
        test1(true); // ok
        test1(false); // die

// read or read and write thi moi shared duoc !
        // => test1: shared == false → exception

        test2(true); // die
        test2(false); // ok

        // => test2: shared == true → exception

        test3(true, true); // ok
        test3(false, true); // ok
        test3(true, false); // ok
        test3(false, false); // ok

        // => test3: どうでもいい  (^ ^)
    }

    public static void test1(boolean shared) throws Exception {
        File testFile = File.createTempFile("/test1", null);
        testFile.deleteOnExit();
        FileInputStream fis = new FileInputStream(testFile);
        FileChannel fc = fis.getChannel();
        FileLock fl = null;
        try {
                fl = fc.lock(0, fc.size(), shared);
           if (!shared)
                throw new RuntimeException("No exception thrown for test1");
        } catch (NonWritableChannelException e) {
            if (shared)
                throw new RuntimeException("Exception thrown for wrong case test1");
        } finally {
            if (fl != null)
                fl.release();
        }
    }

    public static void test2(boolean shared) throws Exception {
        File testFile = File.createTempFile("test2", null);
        testFile.deleteOnExit();
        FileOutputStream fis = new FileOutputStream(testFile);
        FileChannel fc = fis.getChannel();
        FileLock fl = null;
        try {
                fl = fc.tryLock(0, fc.size(), shared);
            if (shared)
                throw new RuntimeException("No exception thrown for test2");
        } catch (NonReadableChannelException e) {
            if (!shared)
                throw new RuntimeException("Exception thrown incorrectly for test2");
        } finally {
            if (fl != null)
                fl.release();
        }
    }

    public static void test3(boolean shared, boolean trylock) throws Exception {
        File testFile = File.createTempFile("test3", null);
        testFile.deleteOnExit();
        RandomAccessFile fis = new RandomAccessFile(testFile, "rw");
        FileChannel fc = fis.getChannel();
        FileLock fl = null;
        if (trylock)
            fl = fc.tryLock(0, fc.size(), shared);
        else
            fl = fc.lock(0, fc.size(), shared);
        fl.release();
    }
}